package com.sq.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sq.dao.PacketResourceDao;
import com.sq.entity.PacketResource;
import com.sq.service.SystemUpdateService;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

@Service
public class SystemUpdateServiceImpl extends ServiceImpl<PacketResourceDao, PacketResource> implements SystemUpdateService  {

    @Override
    public String update(MultipartFile sqai) {
        final String linShiPath = "/Users/admin/Desktop/my-demo/test/update/";
        // 基础校验
        if (sqai.isEmpty()) {
            return "文件不可为空";
        }
        if (!sqai.getOriginalFilename().toLowerCase().endsWith(".zip")) {
            return "请上传ZIP格式文件";
        }
        // 创建安全存储目录
        Path baseDir = Paths.get(linShiPath).normalize();
        if (!baseDir.startsWith(linShiPath)) {
            return "非法存储路径";
        }
        PacketResource distZip=null;
        PacketResource suanFaZip=null;
        try {
            List<String> fileList= unzip(sqai,baseDir);
            Map<String,String> map = new HashMap<>();
            for (String file : fileList) {
                //查询原本的地址
                //生成shell
               PacketResource packetResource= this.getOne(new QueryWrapper<PacketResource>().eq("file_name",file));
               System.out.println(packetResource);
               if(packetResource.getType()==0){
                   map.put(file,packetResource.getPath());
               }
               if(packetResource.getType()==1){
                   distZip=packetResource;
               }
               if(packetResource.getType()==2){
                   suanFaZip=packetResource;
               }
            }
            VelocityEngine velocityEngine = new VelocityEngine();
            velocityEngine.setProperty("resource.loader", "class");
            velocityEngine.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
            velocityEngine.init();
            Template template = velocityEngine.getTemplate("update.vm");
            VelocityContext context = new VelocityContext();
            context.put("map", map);
            context.put("DEST_DIR", "/Users/admin/Desktop/my-demo/test/lishi/");
            context.put("UPDATE_DIR", "/Users/admin/Desktop/my-demo/test/update/sqai/");
            context.put("WORK_DIR","/Users/admin/Desktop/my-demo/test/server/");
            context.put("DIST_DIR","/Users/admin/Desktop/my-demo/test/nginx/");
            String time= new SimpleDateFormat("YY-MM-DD").format(new Date()).toString();
            System.out.println(time);
            context.put("LiShiDistZip","dist-"+time);
            context.put("nginxName","tl-nginx");

            StringWriter writer = new StringWriter();
            template.merge(context, writer);
            System.out.println(writer.toString());
            return "success";
        } catch (IOException e) {
            return e.getMessage();
        }
    }



    private List<String>  unzip(MultipartFile sqai,Path zipPath) throws IOException {
        List<String> extractedFiles = new ArrayList<>();
        Files.createDirectories(zipPath);
        // 解压处理
        ZipInputStream zis = new ZipInputStream(sqai.getInputStream());
        ZipEntry entry;
        byte[] buffer = new byte[4096];
        while ((entry = zis.getNextEntry()) != null) {
            // 安全校验
            Path targetPath = validatePath(zipPath, entry.getName());
            if (entry.isDirectory()) {
                Files.createDirectories(targetPath);
                continue;
            }
            if (entry.getName().startsWith("__MACOSX")) {
                continue;
            }
            // 创建父目录
            Files.createDirectories(targetPath.getParent());
            // 写入文件
            try (OutputStream fos = Files.newOutputStream(targetPath)) {
                int len;
                while ((len = zis.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                }
            }
            String fileName = targetPath.toString().substring(targetPath.toString().lastIndexOf("/") + 1);
            extractedFiles.add(fileName);
            zis.closeEntry();
        }
        return extractedFiles;
    }
    // 路径安全校验方法
    private Path validatePath(Path baseDir, String entryName) throws SecurityException {
        // 过滤路径穿越和绝对路径
        if (entryName.contains("..") || entryName.startsWith("/")) {
            throw new SecurityException("非法文件路径: " + entryName);
        }

        Path targetPath = baseDir.resolve(entryName).normalize();

        // 二次校验路径安全
        if (!targetPath.startsWith(baseDir)) {
            throw new SecurityException("路径越界访问: " + entryName);
        }
        return targetPath;
    }
}
